/*
 * Ext GWT 2.2.4 - Ext for GWT
 * Copyright(c) 2007-2010, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.com/license
 */
package id.co.rho.scoring.cid.client.helper;

import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.data.BaseFilterConfig;
import com.extjs.gxt.ui.client.data.BaseStringFilterConfig;
import com.extjs.gxt.ui.client.data.FilterConfig;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.*;
import com.extjs.gxt.ui.client.util.DelayedTask;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.filters.Filter;
import com.google.gwt.event.dom.client.KeyCodes;

import id.co.rho.scoring.cid.client.listener.OnEnterListener;

import java.util.ArrayList;
import java.util.List;

public class CustomStringFilter<T> extends Filter {

    protected String prefix;
    protected TextField<T> field;
    private int width = 125;

    public static class StringFilterMessages extends FilterMessages {
        private String emptyText = GXT.MESSAGES.stringFilter_emptyText();

        public String getEmptyText() {
            return emptyText;
        }

        public void setEmptyText(String emptyText) {
            this.emptyText = emptyText;
        }
    }

    private DelayedTask updateTask = new DelayedTask(new Listener<BaseEvent>() {
        public void handleEvent(BaseEvent be) {
            fireUpdate();
        }
    });

    public CustomStringFilter(final String dataIndex, final TextField field, final Button submitButton) {
        super(dataIndex);
        init(field, submitButton, null, false);
    }

    public CustomStringFilter(final String dataIndex, TextField field, Button submitButton, Button resetButton) {
        super(dataIndex);
        init(field, submitButton, resetButton, false);
    }

    public CustomStringFilter(final String dataIndex, TextField field, Button submitButton, Button resetButton, boolean enableKeyListener) {
        super(dataIndex);
        init(field, submitButton, resetButton, enableKeyListener);
    }

    private void init(TextField field, Button submitButton, Button resetButton, boolean enableKeyListener) {
        this.field = field;
        if (enableKeyListener) field.addKeyListener(new KeyListener() {
            @Override
            public void componentKeyUp(ComponentEvent event) {
                super.componentKeyUp(event);
                onFieldKeyUp(event);
            }
        });
        field.addKeyListener(new OnEnterListener() {
            @Override
            protected void onKeyUp() {
                fireUpdate();
            }
        });
        submitButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                fireUpdate();
            }
        });
        if (resetButton != null)
            resetButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
                @Override
                public void componentSelected(ButtonEvent ce) {
                    CustomStringFilter.this.field.setValue(null);
                    fireUpdate();
                }
            });
        setWidth(getWidth());

        setMessages(new StringFilterMessages());
    }

    public CustomStringFilter(final String dataIndex, final TextField field, final Button submitButton, String prefix) {
        super(dataIndex);
        this.field = field;
        this.prefix = prefix;

        submitButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                fireUpdate();
            }
        });
        setWidth(getWidth());

        setMessages(new StringFilterMessages());
    }

    @Override
    public StringFilterMessages getMessages() {
        return (StringFilterMessages) super.getMessages();
    }

    @Override
    public List<FilterConfig> getSerialArgs() {
        List<FilterConfig> configs = new ArrayList<FilterConfig>();
        BaseFilterConfig c = new BaseStringFilterConfig("string", getValue());
        c.setField(dataIndex);
        c.setComparison(" like ");
        // untuk field custom karena field BaseFilter akan di overide dengan nilai dataIndex oleh listener yang ada
        c.set("extField", prefix != null ? prefix.concat(dataIndex) : dataIndex);
        configs.add(c);
        return configs;
    }

    @Override
    public Object getValue() {
        return field.getValue();
    }

    /**
     * Returns the field width.
     *
     * @return the field width
     */
    public int getWidth() {
        return width;
    }

    @Override
    public boolean isActivatable() {
        return getValue() != null && getValue().toString().length() > 0;
    }

    @Override
    public void setMessages(FilterMessages messages) {
        super.setMessages(messages);
        if (field != null) {
            field.setEmptyText(getMessages().getEmptyText());
        }
    }

    @Override
    public void setValue(Object value) {
        field.setValue((T) value);
        fireUpdate();
    }

    /**
     * Sets the field width (defaults to 125).
     *
     * @param width the field width
     */
    public void setWidth(int width) {
        this.width = width;
        field.setWidth(width);
    }

    @Override
    public boolean validateModel(ModelData model) {
        String val = getModelValue(model);
        Object value = getValue();
        String v = value == null ? "" : value.toString();
        if (v.length() == 0 && (val == null || val.length() == 0)) {
            return true;
        } else if (val == null) {
            return false;
        } else {
            return val.toLowerCase().indexOf(v.toLowerCase()) > -1;
        }
    }

    protected void onFieldKeyUp(DomEvent fe) {
        int key = fe.getKeyCode();
        if (key == KeyCodes.KEY_ENTER && field.isValid()) {
            fe.stopEvent();
            menu.hide(true);
            return;
        }
        updateTask.delay(getUpdateBuffer());
    }

    private native void blurField(Field<?> f) /*-{
        f.@com.extjs.gxt.ui.client.widget.form.Field::onBlur(Lcom/extjs/gxt/ui/client/event/ComponentEvent;)(null)
    }-*/;

}
